package service

import (
	"strings"

	"gitee.com/sansaniot/ssiot-core/httpmvc/service"
	"github.com/tidwall/sjson"
	"gorm.io/gorm"

	cDto "ssdevice/common/dto"
	"ssdevice/common/utils"
	"ssdevice/internal/device/models"
	"ssdevice/internal/device/models/command"
	"ssdevice/internal/device/models/query"
)

type DevFunc struct {
	sysDevModel     *models.SysDev
	devProductModel *models.SysDevProduct
	devFuncModel    *models.SysDevFunc
	service.Service
}

func (d *DevFunc) SetDevModel(m *models.SysDev) *DevFunc {
	d.sysDevModel = m
	return d
}

func (d *DevFunc) SetProductModel(m *models.SysDevProduct) *DevFunc {
	d.devProductModel = m
	return d
}

func (d *DevFunc) SetFuncModel(m *models.SysDevFunc) *DevFunc {
	d.devFuncModel = m
	return d
}

func (d *DevFunc) SetAllModel() {
	d.sysDevModel = &models.SysDev{}
	d.devProductModel = &models.SysDevProduct{}
	d.devFuncModel = &models.SysDevFunc{}
	d.sysDevModel.Orm = d.Orm
	d.devProductModel.Orm = d.Orm
	d.devFuncModel.Orm = d.Orm
}

// 编辑
func (d *DevFunc) ModDevFunc(req *command.FuncEditReq) (err error) {
	cond := cDto.MakeCondition(query.SysDevFuncQuery{SnOrPm: req.Entity})
	if err = d.devFuncModel.FindOne(d.devFuncModel, cond); err != nil {
		return
	}
	editChildFunc(req, d.devFuncModel)
	err = d.Orm.Transaction(func(tx *gorm.DB) error {
		d.devFuncModel.Orm = tx
		// 更新根变量
		if err = d.devFuncModel.Mod(d.devFuncModel); err != nil {
			return err
		}
		return nil
	})
	return
}

func editChildFunc(req *command.FuncEditReq, devFunc *models.SysDevFunc) {
	if req.Data != nil {
		//data
		childData := map[string]interface{}{req.Key: req.Data}
		// 还原层级
		childData = utils.FixJsonKeyDot(childData)
		// 覆盖子节点data
		dataStr := string(utils.MapToBytes(utils.BytesToMap(devFunc.Data)["func"].(map[string]interface{})))
		dataStr, _ = sjson.Delete(dataStr, req.Key)
		dataStr, _ = sjson.Set(dataStr, req.Key, req.Data)
		devFunc.Data = utils.MapToBytes(map[string]interface{}{"func": utils.BytesToMap([]byte(dataStr))})
		// schema
		childSchema := utils.GetObjectSchema(childData)["properties"].(map[string]interface{})
		childSchemaStr := string(utils.MapToBytes(childSchema))
		p := strings.ReplaceAll(req.Key, ".", ".properties.")
		if len(req.Label) > 0 {
			childSchemaStr, _ = sjson.Set(childSchemaStr, p+".title", req.Label)
		}
		childSchema = utils.BytesToMap([]byte(childSchemaStr))
		childSchemaData := utils.GetFieldFromJson(strings.Split(p, "."), childSchema)
		// 覆盖子节点schema
		schemaStr := string(utils.MapToBytes(utils.BytesToMap(devFunc.Schema)["func"].(map[string]interface{})["properties"].(map[string]interface{})))
		schemaStr, _ = sjson.Delete(schemaStr, p)
		schemaStr, _ = sjson.Set(schemaStr, p, childSchemaData)
		devFunc.Schema = utils.MapToBytes(map[string]interface{}{"func": map[string]interface{}{"properties": utils.BytesToMap([]byte(schemaStr))}})
	} else {
		schemaStr := string(utils.MapToBytes(utils.BytesToMap(devFunc.Schema)["func"].(map[string]interface{})["properties"].(map[string]interface{})))
		if len(req.Label) > 0 {
			p := strings.ReplaceAll(req.Key, ".", ".properties.")
			schemaStr, _ = sjson.Set(schemaStr, p+".title", req.Label)
			devFunc.Schema = utils.MapToBytes(map[string]interface{}{"func": map[string]interface{}{"properties": utils.BytesToMap([]byte(schemaStr))}})
		}
	}

}
